Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure NoJump handles jumps that occur on the second frame in NPT trajectories #4258

Merged
merged 42 commits into from
Sep 3, 2023

Conversation

p-j-smith
Copy link
Member

@p-j-smith p-j-smith commented Aug 26, 2023

Fixes #4257

Changes made in this Pull Request:

  • ensure jumps across periodic boundaries that occur at the second frame are accounted for by mda.transformations.NoJump

  • added two tests:

    • test_nojump_2nd_frame.- tests that jumps that occur on the second frame are handled correctly
    • test_nojump_3rd_frame.- tests that jumps that occur on the third frame are handled correctly
  • the test_nojump_3rd_frame test isn't necessary and can probably be removed. However, I've included it here to illustrate the the fix in this pr is necessary. Before this pr, test_nojump_3rd_frame would pass but test_nojump_2nd_frame would fail, and the only difference between the trajectories is the frame at which the jump across a boundary occurs

  • the fix requires that we know the atom positions and box size at the first frame of the trajectory, and so I've added an ag argument that takes an AtomGroup to be unwrapped. This however would be a breaking change to the api. Perhaps a better way would be to add an if-statement to mda.transformations.NoJump._transform that checks if we're on the first frame of the trajectory, and if so then sets the appropriate values for NoJump.prev, NoJump.old_frame, and NoJump.older_frame?

  • updated all other tests for nojump to use the required ag argument

Note, I've temporarily put the test datasets in the testsuite itself so the tests can run before the datasets are added to MDAnalysisData

Edit: I was running into some issues with CI failing because the test datafiles I added weren't present in MDAnalysisData. So I've added a tranformation mda.transformations.boxdimensions.set_variable_dimensions to set different box dimensions at each frame (so we can create an NPT trajectory to go with mda.Universe.empty).

PR Checklist

  • Tests?
  • Docs?
  • CHANGELOG updated?
  • Issue raised/referenced?

Developers certificate of origin

@github-actions
Copy link

github-actions bot commented Aug 26, 2023

Linter Bot Results:

Hi @p-j-smith! Thanks for making this PR. We linted your code and found the following:

Some issues were found with the formatting of your code.

Code Location Outcome
main package ⚠️ Possible failure
testsuite ⚠️ Possible failure

Please have a look at the darker-main-code and darker-test-code steps here for more details: https://github.com/MDAnalysis/mdanalysis/actions/runs/6064286779/job/16452562369


Please note: The black linter is purely informational, you can safely ignore these outcomes if there are no flake8 failures!

@codecov
Copy link

codecov bot commented Aug 26, 2023

Codecov Report

Patch coverage: 100.00% and no project coverage change.

Comparison is base (2acd594) 93.40% compared to head (de33028) 93.40%.

Additional details and impacted files
@@            Coverage Diff             @@
##           develop    #4258     +/-   ##
==========================================
  Coverage    93.40%   93.40%             
==========================================
  Files          170      184     +14     
  Lines        22246    23358   +1112     
  Branches      4071     4071             
==========================================
+ Hits         20779    21818   +1039     
- Misses         951     1024     +73     
  Partials       516      516             
Files Changed Coverage Δ
...ackage/MDAnalysis/transformations/boxdimensions.py 100.00% <100.00%> (ø)
package/MDAnalysis/transformations/nojump.py 100.00% <100.00%> (ø)

... and 14 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@p-j-smith
Copy link
Member Author

the fix requires that we know the atom positions and box size at the first frame of the trajectory, and so I've added an ag argument that takes an AtomGroup to be unwrapped. This however would be a breaking change to the api. Perhaps a better way would be to add an if-statement to mda.transformations.NoJump._transform that checks if we're on the first frame of the trajectory, and if so then sets the appropriate values for NoJump.prev, NoJump.old_frame, and NoJump.older_frame?

I've removed the ag argument I added and gone with using an if-statement to check it we're on the first frame. This both avoids a breaking change and ensures the trajectory can be iterated over multiple times and unwrapping still be performed correctly. I've also added a test to check that coordinates are always unwrapped correctly when iterating multiple times.

Copy link
Member

@hmacdope hmacdope left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tiny little nitpicks, but other than that looking great. Don't forget CHANGELOG ;)

package/MDAnalysis/transformations/boxdimensions.py Outdated Show resolved Hide resolved
testsuite/MDAnalysisTests/transformations/test_nojump.py Outdated Show resolved Hide resolved
@p-j-smith
Copy link
Member Author

thanks for the speedy review @hmacdope! And sorry for mixing a fix and a feature in the same pr - I probably should have added set_variable_dimensions separately :)

Copy link
Member

@IAlibay IAlibay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One initial blocking request - I'll follow up with smaller review things.

@@ -92,3 +93,74 @@ def __init__(self,
def _transform(self, ts):
ts.dimensions = self.dimensions
return ts


class set_variable_dimensions(TransformationBase):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we just move this new functionality as a new option of the existing set_dimension? The order of how things are done is very similar and it would be a much better user experience to not have to deal with (choose between) a lot of classes that do very similar things.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep I think that would make sense

Comment on lines 116 to 119
dim = [
[2, 2, 2, 90, 90, 90],
[4, 4, 4, 90, 90, 90],
]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use a numpy array in the example if possible

Copy link
Member

@IAlibay IAlibay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the "small changes" review

package/CHANGELOG Outdated Show resolved Hide resolved
try:
ts.dimensions = self.dimensions[ts.frame]
except IndexError as e:
raise NoDataError(f"Dimensions array has no data for frame {ts.frame}") from e
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per #3901, NoDataError is really only meant to exist within the realm of TopologyAttr. A ValueError probably should be used here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah okay, that's good to know

ts = variable_boxdimensions_universe.trajectory.ts
with pytest.raises(ValueError, match='valid box dimension shape'):
set_variable_dimensions(dim_vector_shapes)(ts)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

p-j-smith and others added 21 commits August 28, 2023 10:09
… on the second frame

Previosuly, jumps wouldn't be unwrapped until the third frame due to the way the class was initialised.
To fix the issue, the NoJump transformation now requires an 'ag' argument, which is used to determine the box size at the first frame
…nd and third frames

Also update other tests to pass the 'ag' argument to the transformation
…values at all frames when iterating over multiple times
…ted unwrapping

Also don't pass 'ag' argument to NoJump in tests
Co-authored-by: Hugo MacDermott-Opeskin <[email protected]>
Co-authored-by: Hugo MacDermott-Opeskin <[email protected]>
@p-j-smith p-j-smith force-pushed the fix/no-jump-first-frame branch from 5cbba9c to 2a2d100 Compare August 28, 2023 09:10
@p-j-smith
Copy link
Member Author

Thanks for the reviews @richardjgowers and @IAlibay ! I think I've addressed all your comments, and I've just rebased on to the latest develop

Copy link
Member

@IAlibay IAlibay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple more small things, otherwise lgtm

package/MDAnalysis/transformations/nojump.py Show resolved Hide resolved
'[a, b, c, alpha, beta, gamma]')
raise ValueError(errmsg)

def _transform(self, ts):
ts.dimensions = self.dimensions
try:
ts.dimensions = self.dimensions[0] if self.dimensions.shape[0] == 1 else self.dimensions[ts.frame]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is both a long line and also a bit hard to read (at least to me), splitting this over a few lines probably would be worth it?

try:
ts.dimensions = self.dimensions[0] if self.dimensions.shape[0] == 1 else self.dimensions[ts.frame]
except IndexError as e:
raise ValueError(f"Dimensions array has no data for frame {ts.frame}") from e
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
raise ValueError(f"Dimensions array has no data for frame {ts.frame}") from e
errmsg = f"Dimensions array has no data for frame {ts.frame}"
raise ValueError(errmsg) from e

I know it's annoying but pep8 - note we don't care about the black linter stuff, but the flake8 errors from here probably should be addressed: https://github.com/MDAnalysis/mdanalysis/actions/runs/5997923144/job/16265248319

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah sorry I forgot to run flake8 locally, fixed now! Perhaps adding a pre-commit config for people to optionally use would be useful?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pre-commit config for people to optionally use would be useful?

It's.. complicated, I'll leave it as that for now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha! okay :)

@p-j-smith
Copy link
Member Author

I just realised that with the changes in this pr there are now some parts of NoJump that are not tested (because of the early return statement). I'll add tests for them tomorrow

@orbeckst
Copy link
Member

@hmacdope could you be the one looking after this PR, chasing reviews if necessary, and merging, i.e., assign it to you?

@hmacdope
Copy link
Member

@hmacdope could you be the one looking after this PR, chasing reviews if necessary, and merging, i.e., assign it to you?

Yep, ill re-review ASAP.

@hmacdope hmacdope self-assigned this Aug 31, 2023
Copy link
Member

@IAlibay IAlibay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm thanks!

@IAlibay IAlibay requested a review from hmacdope September 2, 2023 11:40
Copy link
Member

@hmacdope hmacdope left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me @p-j-smith. Thank you so much for the detailed bug report, timely fix and detailed testing! Its really appreciated.

@hmacdope hmacdope merged commit f50a097 into MDAnalysis:develop Sep 3, 2023
@p-j-smith
Copy link
Member Author

Thanks for the speedy reviews everyone!

@orbeckst
Copy link
Member

orbeckst commented Sep 3, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NoJump transformation ignores jumps across boundaries on the second frame for NPT trajectories
5 participants